import { kebabCase, camelCase } from './utils';
import { compose, map, trim, split, adjust, toPairs, join, filter, all, fromPairs } from 'ramda';


// style stirng => object

type Pair = [string, string]
type Style = {[k: string]: string}
type AttrPair = [string|number, string]

const style2pair: (s: string) => Pair = s => {

    let [k, v] = compose(map(trim), split(':'))(s)

    return [camelCase(k), v&&v.toString()]
}

export const toStyle = compose<string, string[], Pair[], Pair[], Style>(fromPairs, filter<Pair>(all(Boolean)), map(style2pair), split(';'))

// object to style string

export const toString: (s: Style) => string = compose<Style, Pair[], string[], string>(join(';'), map(compose(join(':'), adjust(kebabCase, 0))), toPairs)

export const toAttrPair = (v: string) :AttrPair => {
    let [value, unit] = [parseFloat(v), v.toString().match(/\D*$/)[0]]

    return (isNaN(value) || value + unit !== v) 
    ? [v, '']
    : [value, unit]
}

const canClear = (t: AttrPair): boolean => {
    return false
}

export const clear = (style: string|Style, notAllows: string[] = []): Style => {
    if (typeof style === 'string') style = toStyle(style)
    if (!style) return {}
    for (let key of Object.keys(style)) {
        let [v, unit] = toAttrPair(style[key])
        
        if (unit === 'px') v = typeof v === 'string' ? parseInt(v) : Math.round(v)

        if (canClear([v, unit]) || notAllows.includes(key)) {
            delete style[key]
        } else {
            style[key] = `${v}${unit}`
        }
    }

    return style
}